<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>为什么装饰器不能用于函数</title>
</head>
<body>
    <h1>为什么装饰器不能用于函数</h1>

    <script>
        // 函数声明会提升，但装饰器不会提升
        // 这会导致装饰器无法正确装饰函数
        /*
        @decorator
        function foo() {}
        */

        // 替代方案1：使用函数表达式
        const foo = decorator(function() {});

        // 替代方案2：使用高阶函数
        function log(fn) {
            return function(...args) {
                console.log('调用函数:', fn.name);
                return fn.apply(this, args);
            };
        }

        const add = log(function add(a, b) {
            return a + b;
        });

        // 实际应用示例
        // 1. 函数性能监控
        function measure(fn) {
            return function(...args) {
                const start = performance.now();
                const result = fn.apply(this, args);
                const end = performance.now();
                console.log(`${fn.name} 执行时间: ${end - start}ms`);
                return result;
            };
        }

        const slowFunction = measure(function slowFunction() {
            let result = 0;
            for(let i = 0; i < 1000000; i++) {
                result += i;
            }
            return result;
        });

        // 2. 函数缓存
        function memoize(fn) {
            const cache = new Map();
            return function(...args) {
                const key = JSON.stringify(args);
                if (cache.has(key)) {
                    return cache.get(key);
                }
                const result = fn.apply(this, args);
                cache.set(key, result);
                return result;
            };
        }

        const fibonacci = memoize(function fibonacci(n) {
            if (n <= 1) return n;
            return fibonacci(n - 1) + fibonacci(n - 2);
        });

        // 3. 函数重试
        function retry(fn, times = 3, delay = 1000) {
            return async function(...args) {
                for (let i = 0; i < times; i++) {
                    try {
                        return await fn.apply(this, args);
                    } catch (error) {
                        if (i === times - 1) throw error;
                        await new Promise(resolve => setTimeout(resolve, delay));
                        console.log(`重试第${i + 1}次`);
                    }
                }
            };
        }

        const fetchWithRetry = retry(async function fetchData(url) {
            const response = await fetch(url);
            return response.json();
        });
    </script>
</body>
</html> 